Allow EVTCHNOP_bind_{ipi,virq} to specify the vcpu to
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 4 Oct 2005 14:02:51 +0000 (15:02 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Tue, 4 Oct 2005 14:02:51 +0000 (15:02 +0100)
bind to. Previously the alloacted port was implicitly
bound to the calling vcpu.

Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c
tools/libxc/xc_evtchn.c
xen/common/event_channel.c
xen/include/public/event_channel.h

index 99f928e1a355f1f48ab35925db237c16622f36af..647f1f240b141428baa6c2433de33dbb8c3a612c 100644 (file)
@@ -189,6 +189,7 @@ int bind_virq_to_irq(int virq)
        if ((irq = per_cpu(virq_to_irq, cpu)[virq]) == -1) {
                op.cmd              = EVTCHNOP_bind_virq;
                op.u.bind_virq.virq = virq;
+               op.u.bind_virq.vcpu = cpu;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_virq.port;
 
@@ -252,6 +253,7 @@ int bind_ipi_to_irq(int ipi)
 
        if ((evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]) == -1) {
                op.cmd = EVTCHNOP_bind_ipi;
+               op.u.bind_ipi.vcpu = cpu;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_ipi.port;
 
@@ -666,6 +668,7 @@ void irq_resume(void)
                /* Get a new binding from Xen. */
                op.cmd              = EVTCHNOP_bind_virq;
                op.u.bind_virq.virq = virq;
+               op.u.bind_virq.vcpu = 0;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_virq.port;
         
@@ -687,6 +690,7 @@ void irq_resume(void)
 
                /* Get a new binding from Xen. */
                op.cmd = EVTCHNOP_bind_ipi;
+               op.u.bind_ipi.vcpu = 0;
                BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
                evtchn = op.u.bind_ipi.port;
         
index 74e8468dd54749a1b5a1daeba5bf27207010a46c..f7698d354187acc93dcc1a6e663fc55104d9f1a8 100644 (file)
@@ -90,7 +90,8 @@ int xc_evtchn_bind_virq(int xc_handle,
 
     op.cmd = EVTCHNOP_bind_virq;
     op.u.bind_virq.virq = (u32)virq;
-   
+    op.u.bind_virq.vcpu = 0;
+
     if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
     {
         if ( port != NULL )
index 6ad5c2578853e7bf187991eda545e8fb4bdaefe4..8c413097ba16ac4ee51c11ae98f4cd9220b97f08 100644 (file)
@@ -244,15 +244,15 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
 static long evtchn_bind_virq(evtchn_bind_virq_t *bind)
 {
     struct evtchn *chn;
-    struct vcpu   *v = current;
-    struct domain *d = v->domain;
+    struct vcpu   *v;
+    struct domain *d = current->domain;
     int            port, virq = bind->virq;
 
     if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
         return -EINVAL;
 
-    if ( d->domain_id == 0 && virq >= VIRQ_CONSOLE )
-        v = d->vcpu[0];
+    if ( (v = d->vcpu[bind->vcpu]) == NULL )
+        return -ENOENT;
 
     spin_lock(&d->evtchn_lock);
 
@@ -288,13 +288,16 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
     struct domain *d = current->domain;
     int            port;
 
+    if ( d->vcpu[bind->vcpu] == NULL )
+        return -ENOENT;
+
     spin_lock(&d->evtchn_lock);
 
     if ( (port = get_free_port(d)) >= 0 )
     {
         chn = evtchn_from_port(d, port);
         chn->state          = ECS_IPI;
-        chn->notify_vcpu_id = current->vcpu_id;
+        chn->notify_vcpu_id = bind->vcpu;
     }
 
     spin_unlock(&d->evtchn_lock);
index d1629ec2446c7602c60d64384797da55c8bf731f..443be607f84efc7ea65c6a487ff3c142a0872d51 100644 (file)
@@ -51,22 +51,24 @@ typedef struct evtchn_bind_interdomain {
 } evtchn_bind_interdomain_t;
 
 /*
- * EVTCHNOP_bind_virq: Bind a local event channel to IRQ <irq> on calling vcpu.
+ * EVTCHNOP_bind_virq: Bind a local event channel to VIRQ <irq> on specified
+ * vcpu.
  * NOTES:
  *  1. A virtual IRQ may be bound to at most one event channel per vcpu.
- *  2. The allocated event channel is bound to the calling vcpu. The binding
+ *  2. The allocated event channel is bound to the specified vcpu. The binding
  *     may not be changed.
  */
 #define EVTCHNOP_bind_virq        1
 typedef struct evtchn_bind_virq {
     /* IN parameters. */
     u32 virq;
+    u32 vcpu;
     /* OUT parameters. */
     u32 port;
 } evtchn_bind_virq_t;
 
 /*
- * EVTCHNOP_bind_pirq: Bind a local event channel to IRQ <irq>.
+ * EVTCHNOP_bind_pirq: Bind a local event channel to PIRQ <irq>.
  * NOTES:
  *  1. A physical IRQ may be bound to at most one event channel per domain.
  *  2. Only a sufficiently-privileged domain may bind to a physical IRQ.
@@ -84,11 +86,12 @@ typedef struct evtchn_bind_pirq {
 /*
  * EVTCHNOP_bind_ipi: Bind a local event channel to receive events.
  * NOTES:
- *  1. The allocated event channel is bound to the calling vcpu. The binding
+ *  1. The allocated event channel is bound to the specified vcpu. The binding
  *     may not be changed.
  */
 #define EVTCHNOP_bind_ipi         7
 typedef struct evtchn_bind_ipi {
+    u32 vcpu;
     /* OUT parameters. */
     u32 port;
 } evtchn_bind_ipi_t;